﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SGD;
using System.IO;
using System.Xml.Linq;
using System.Diagnostics;

namespace DirectXTest
{
    public partial class Form1 : Form
    {
        //Wrappers
        ManagedDirect3D d3d;
        ManagedTextureManager texManager;

        bool draw = false;
        Point cursorPosition;
        int frameSelected;
        bool previewMode;
        bool playAnimation;
        bool loopingAnimation;
        int frameTextureID;
        int timeLineTextureID;
        string imageFilePath;

        Uri systemPath;
        Uri imagePath;
        Uri filePath;

        Point rectStart;
        Point rectEnd;

        long startTime;
        long currTime;

        int toolSelected;
        bool loadValues;

        int maxFrames;
        Rectangle frameRect;

        bool keyPressed;

        bool isRunning;
        int textureID;

        List<Animation> animations;
        Animation currAnimation;
        int currAnimationID;
        //List<Frame> currAnimation.frames;

        public Form1()
        {
            currTime = 0;
            loopingAnimation = true;
            startTime = Environment.TickCount;
            
            rectStart = Point.Empty;
            rectEnd = Point.Empty;

            animations = new List<Animation>();

            loadValues = false;
            keyPressed = false;
            previewMode = false;
            playAnimation = false;

            maxFrames = 0;
            frameSelected = -1;

            toolSelected = 0;

            textureID = -1;
            InitializeComponent();
            d3d = ManagedDirect3D.Instance;
            texManager = ManagedTextureManager.Instance;
            isRunning = true;
            
            canvasPanel.KeyDown += new KeyEventHandler(OnKeypress);
            canvasPanel.PreviewKeyDown += new PreviewKeyDownEventHandler(PreviewKey);

            if (!d3d.InitManagedDirect3D(canvasPanel, false))
                MessageBox.Show("Could not init D3D", "MEDUSA TILE", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);

            texManager.InitManagedTextureManager(d3d.Device, d3d.Sprite);

            currAnimation = new Animation();
            currAnimation.IsLooping = true;
            currAnimation.Name = "Untitled Animation";
            currAnimationID = 0;
            currAnimation.frames = new List<Frame>();
            
            animations.Add(currAnimation);

            animationsListBox.Items.Add("Untitled Animation");

            animationsListBox.SelectedIndex = 0;
            modeComboBox.SelectedIndex = 0;

            d3d.ChangeDisplayParam(canvasPanel,canvasPanel.Width-20, canvasPanel.Height-20, true, false);

            OpenSystemTextFile();

            if (File.Exists("Resources\\Tools\\frame.png"))
                frameTextureID = texManager.LoadTexture("Resources\\Tools\\frame.png", 0);
            else
                MessageBox.Show("Corrupt installation detected, please reinstall the program to ensure proper execution");

            if (File.Exists("Resources\\Tools\\timeguide.png"))
                timeLineTextureID = texManager.LoadTexture("Resources\\Tools\\timeguide.png", 0);
            else
                MessageBox.Show("Corrupt installation detected, please reinstall the program to ensure proper execution");
        }

        public void PreviewKey(object sender, PreviewKeyDownEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    {
                        if (frameSelected != -1)
                        {
                            keyPressed = true;
                            canvasPanel.Focus();
                            if (toolSelected == 0)
                            {
                                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                                if (auxRect.Top > 0)
                                {
                                    auxRect = new Rectangle(auxRect.Left, auxRect.Top - 1, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                    currAnimation.frames[frameSelected].drawRect = auxRect;
                                    loadValues = true;
                                    framePosYNumUpDown.Value = auxRect.Top;
                                    loadValues = false;
                                }
                            }
                            else if (toolSelected == 1)
                            {
                                Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                                if (auxRect.Top > 0 && currAnimation.frames[frameSelected].DrawRect.Top < currAnimation.frames[frameSelected].CollisionRect.Top)
                                {
                                    auxRect = new Rectangle(auxRect.Left, auxRect.Top - 1, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                    currAnimation.frames[frameSelected].CollisionRect = auxRect;
                                    loadValues = true;
                                    collisionPosYNumUpDown.Value = auxRect.Top;
                                    loadValues = false;
                                }
                            }
                            else if (toolSelected == 2)
                            {
                                currAnimation.frames[frameSelected].AnchorPoint = new Point(currAnimation.frames[frameSelected].AnchorPoint.X, currAnimation.frames[frameSelected].AnchorPoint.Y - 1);
                                loadValues = true;
                                anchorPosYNumUpDown.Value = currAnimation.frames[frameSelected].AnchorPoint.Y;
                                loadValues = false;
                            }
                        }
                    }
                    break;
                case Keys.Down:
                    {
                        if (frameSelected != -1)
                        {
                            keyPressed = true;
                            canvasPanel.Focus();
                            if (toolSelected == 0)
                            {
                                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                                auxRect = new Rectangle(auxRect.Left, auxRect.Top + 1, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                currAnimation.frames[frameSelected].drawRect = auxRect;
                                loadValues = true;
                                framePosYNumUpDown.Value = auxRect.Top;
                                loadValues = false;
                                canvasPanel.Focus();
                            }
                            else if (toolSelected == 1)
                            {
                                if (currAnimation.frames[frameSelected].DrawRect.Bottom > currAnimation.frames[frameSelected].CollisionRect.Bottom)
                                {
                                    Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                                    auxRect = new Rectangle(auxRect.Left, auxRect.Top + 1, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                    currAnimation.frames[frameSelected].CollisionRect = auxRect;
                                    loadValues = true;
                                    collisionPosYNumUpDown.Value = auxRect.Top;
                                    loadValues = false;
                                    canvasPanel.Focus();
                                }
                            }
                            else if (toolSelected == 2)
                            {
                                currAnimation.frames[frameSelected].AnchorPoint = new Point(currAnimation.frames[frameSelected].AnchorPoint.X, currAnimation.frames[frameSelected].AnchorPoint.Y + 1);
                                loadValues = true;
                                anchorPosYNumUpDown.Value = currAnimation.frames[frameSelected].AnchorPoint.Y;
                                loadValues = false;
                            }
                        }
                    }
                    break;

                case Keys.Right:
                    {
                        if (frameSelected != -1)
                        {
                            keyPressed = true;
                            canvasPanel.Focus();
                            if (toolSelected == 0)
                            {
                                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                                auxRect = new Rectangle(auxRect.Left + 1, auxRect.Top, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                currAnimation.frames[frameSelected].drawRect = auxRect;
                                loadValues = true;
                                framePosXNumUpDown.Value = auxRect.Left;
                                loadValues = false;
                                canvasPanel.Focus();
                            }
                            else if (toolSelected == 1)
                            {
                                if (currAnimation.frames[frameSelected].DrawRect.Right > currAnimation.frames[frameSelected].CollisionRect.Right)
                                {
                                    Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                                    auxRect = new Rectangle(auxRect.Left + 1, auxRect.Top, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                    currAnimation.frames[frameSelected].CollisionRect = auxRect;
                                    loadValues = true;
                                    collisionPosXNumUpDown.Value = auxRect.Left;
                                    loadValues = false;
                                    canvasPanel.Focus();
                                }
                            }
                            else if (toolSelected == 2)
                            {
                                currAnimation.frames[frameSelected].AnchorPoint = new Point(currAnimation.frames[frameSelected].AnchorPoint.X+1, currAnimation.frames[frameSelected].AnchorPoint.Y);
                                loadValues = true;
                                anchorPosYNumUpDown.Value = currAnimation.frames[frameSelected].AnchorPoint.X;
                                loadValues = false;
                            }
                        }
                    }
                    break;

                case Keys.Left:
                    {
                        if (frameSelected != -1)
                        {
                            keyPressed = true;
                            canvasPanel.Focus();
                            if (toolSelected == 0)
                            {
                                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                                if (auxRect.Left > 0)
                                {
                                    auxRect = new Rectangle(auxRect.Left - 1, auxRect.Top, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                    currAnimation.frames[frameSelected].drawRect = auxRect;
                                    loadValues = true;
                                    framePosXNumUpDown.Value = auxRect.Left;
                                    loadValues = false;
                                }
                            }
                            else if (toolSelected == 1)
                            {
                                Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                                if (auxRect.Left > 0 && currAnimation.frames[frameSelected].DrawRect.Left < currAnimation.frames[frameSelected].CollisionRect.Left)
                                {
                                    auxRect = new Rectangle(auxRect.Left - 1, auxRect.Top, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                                    currAnimation.frames[frameSelected].CollisionRect = auxRect;
                                    loadValues = true;
                                    collisionPosXNumUpDown.Value = auxRect.Left;
                                    loadValues = false;
                                }
                            }
                            else if (toolSelected == 2)
                            {
                                currAnimation.frames[frameSelected].AnchorPoint = new Point(currAnimation.frames[frameSelected].AnchorPoint.X - 1, currAnimation.frames[frameSelected].AnchorPoint.Y);
                                loadValues = true;
                                anchorPosYNumUpDown.Value = currAnimation.frames[frameSelected].AnchorPoint.X;
                                loadValues = false;
                            }
                        }
                    }
                    break;
            }
        }

        public void OnKeypress(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Delete:
                    {
                        if (frameSelected != -1)
                        {
                            if (toolSelected == 0)
                            {
                                currAnimation.frames.RemoveAt(frameSelected);
                                maxFrames--;
                                frameSelected = -1;

                                loadValues = true;
                                totalFramesNumericUpDown.Value = maxFrames;
                                frameWidthNumUpDown.Value = 0;
                                frameHeightNumUpDown.Value = 0;
                                framePosXNumUpDown.Value = 0;
                                framePosYNumUpDown.Value = 0;

                                collisionWidthNumUpDown.Value = 0;
                                collisionHeightNumUpDown.Value = 0;
                                collisionPosXNumUpDown.Value = 0;
                                collisionPosYNumUpDown.Value = 0;

                                anchorPosXNumUpDown.Value = 0;
                                anchorPosYNumUpDown.Value = 0;
                                loadValues = false;
                            }
                            if (toolSelected == 1)
                            {
                                currAnimation.frames[frameSelected].CollisionRect = Rectangle.Empty;
                                loadValues = true;
                                totalFramesNumericUpDown.Value = maxFrames;

                                collisionWidthNumUpDown.Value = 0;
                                collisionHeightNumUpDown.Value = 0;
                                collisionPosXNumUpDown.Value = 0;
                                collisionPosYNumUpDown.Value = 0;
                                loadValues = false;
                            }
                        }
                    }
                    break;
                case Keys.Q:
                    {
                        frameRectButton.Enabled = false;
                        anchorPointButton.Enabled = true;
                        collisionRectButton.Enabled = true;
                        toolSelected = 0;
                    }
                    break;
                case Keys.W:
                    {
                        frameRectButton.Enabled = true;
                        anchorPointButton.Enabled = true;
                        collisionRectButton.Enabled = false;
                        toolSelected = 1;
                    }
                    break;
                case Keys.E:
                    {
                        frameRectButton.Enabled = true;
                        anchorPointButton.Enabled = false;
                        collisionRectButton.Enabled = true;
                        toolSelected = 2;
                    }
                    break;
            }

        }

        public void Update()
        {
            if (playAnimation)
            {
                currTime = Environment.TickCount - startTime;
                if (currTime > currAnimation.frames[frameSelected].frameTime)
                {
                    frameSelected++;
                    if (frameSelected >= maxFrames)
                    {
                        if (loopingAnimation)
                            frameSelected = 0;
                        else
                            frameSelected--;
                    }
                    LoadValues();

                    startTime = Environment.TickCount;
                }
            }
        }

        public void Render()
        {
            int posX = canvasPanel.AutoScrollPosition.X;
            int posY = canvasPanel.AutoScrollPosition.Y;

            d3d.Clear(255,255,255);
            d3d.DeviceBegin();
            d3d.SpriteBegin();

            if (!previewMode)
            {
                if (textureID != -1)
                {
                    frameRect = new Rectangle(-canvasPanel.AutoScrollPosition.X,
                                                -canvasPanel.AutoScrollPosition.Y,
                                                (-canvasPanel.AutoScrollPosition.X) + canvasPanel.Width,
                                                (-canvasPanel.AutoScrollPosition.X) + canvasPanel.Height);

                    int width = texManager.GetTextureHeight(textureID);
                    texManager.Draw(textureID, 0, 0, 1.0f, 1.0f, frameRect, 0, 0, 0.0f, 0);
                }

                d3d.Sprite.Flush();

                for (int i = 0; i < currAnimation.frames.Count; ++i)
                {
                    Point offset = Point.Empty;

                    offset.X -= canvasPanel.AutoScrollPosition.X;
                    offset.Y -= canvasPanel.AutoScrollPosition.Y;

                    int x1 = currAnimation.frames[i].DrawRect.Left;
                    int x2 = currAnimation.frames[i].DrawRect.Left;
                    int x3 = currAnimation.frames[i].DrawRect.Left;
                    int x4 = currAnimation.frames[i].DrawRect.Right;

                    d3d.DrawLine(currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, 0, 0, 255);
                    d3d.DrawLine(currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, 0, 0, 255);
                    d3d.DrawLine(currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, 0, 0, 255);
                    d3d.DrawLine(currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, 0, 0, 255);

                    d3d.DrawLine(currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, 0, 255, 0);
                    d3d.DrawLine(currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, 0, 255, 0);
                    d3d.DrawLine(currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, 0, 255, 0);
                    d3d.DrawLine(currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, 0, 255, 0);

                    d3d.DrawRect(new Rectangle(currAnimation.frames[i].AnchorPoint.X - 3 - offset.X, currAnimation.frames[i].AnchorPoint.Y - 3 - offset.Y, 6, 6), 255, 0, 255);

                    if (frameSelected == i)
                    {
                        if (toolSelected == 0)
                        {
                            d3d.DrawLine(currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, 255, 0, 0);
                            d3d.DrawLine(currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, 255, 0, 0);
                            d3d.DrawLine(currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, currAnimation.frames[i].DrawRect.Left - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, 255, 0, 0);
                            d3d.DrawLine(currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Top - offset.Y, currAnimation.frames[i].DrawRect.Right - offset.X, currAnimation.frames[i].DrawRect.Bottom - offset.Y, 255, 0, 0);
                        }
                        else if (toolSelected == 1)
                        {
                            d3d.DrawLine(currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, 255, 0, 0);
                            d3d.DrawLine(currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, 255, 0, 0);
                            d3d.DrawLine(currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, currAnimation.frames[i].CollisionRect.Left - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, 255, 0, 0);
                            d3d.DrawLine(currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Top - offset.Y, currAnimation.frames[i].CollisionRect.Right - offset.X, currAnimation.frames[i].CollisionRect.Bottom - offset.Y, 255, 0, 0);
                        }
                    }
                }

                if (draw && rectStart != Point.Empty)
                {
                    Point offset = Point.Empty;

                    offset.X -= canvasPanel.AutoScrollPosition.X;
                    offset.Y -= canvasPanel.AutoScrollPosition.Y;

                    d3d.DrawLine(rectStart.X - offset.X, rectStart.Y - offset.Y, rectEnd.X - offset.X, rectStart.Y - offset.Y, 255, 0, 0);
                    d3d.DrawLine(rectStart.X - offset.X, rectEnd.Y - offset.Y, rectEnd.X - offset.X, rectEnd.Y - offset.Y, 255, 0, 0);
                    d3d.DrawLine(rectStart.X - offset.X, rectStart.Y - offset.Y, rectStart.X - offset.X, rectEnd.Y - offset.Y, 255, 0, 0);
                    d3d.DrawLine(rectEnd.X - offset.X, rectStart.Y - offset.Y, rectEnd.X - offset.X, rectEnd.Y - offset.Y, 255, 0, 0);
                }
            }
            else
            {
                if (currAnimation.frames.Count > 0)
                {
                    if (textureID != -1)
                    {
                        for (int i = 0; i < currAnimation.frames.Count; i++)
                            texManager.Draw(frameTextureID, i * 8, canvasPanel.Height - 32, 1.0f, 1.0f, Rectangle.Empty, 0, 0, 0.0f, 0);
                        int imageOffsetX = currAnimation.frames[frameSelected].AnchorPoint.X - currAnimation.frames[frameSelected].DrawRect.Left;
                        int imageOffsetY = currAnimation.frames[frameSelected].AnchorPoint.Y - currAnimation.frames[frameSelected].DrawRect.Top;
                        texManager.Draw(textureID, canvasPanel.Width / 2 - imageOffsetX, canvasPanel.Height / 2 - imageOffsetY, 1.0f, 1.0f, currAnimation.frames[frameSelected].DrawRect, 0, 0, 0.0f, 0);

                        texManager.Draw(timeLineTextureID, frameSelected * 8, canvasPanel.Height - 32, 1.0f, 1.0f, Rectangle.Empty, 0, 0, 0.0f, 0);
                    }
                }
            }

            d3d.SpriteEnd();
            d3d.DeviceEnd();

            d3d.Present();
        }

        public bool IsRunning()
        {
            return isRunning;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            isRunning = false;
            texManager.ShutdownManagedTextureManager();
        }

        private void filenameLabel_Click(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Files|*.*|jpeg|*.jpg|png|*.png|bmp|*.bmp";
            dlg.FilterIndex = 1;

            if (DialogResult.OK == dlg.ShowDialog())
            {
                filePath = new Uri(dlg.FileName);

                filePath = systemPath.MakeRelativeUri(filePath);
                textureID = texManager.LoadTexture(dlg.FileName, 0);

                canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
                startTime = Environment.TickCount;
                currTime = startTime;
            }
        }

        private void totalFramesNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            maxFrames = (int)totalFramesNumericUpDown.Value;
        }

        private void columnsNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
        }

        private void canvasPanel_MouseMove(object sender, MouseEventArgs e)
        {
            Point offset = e.Location;

            offset.X -= canvasPanel.AutoScrollPosition.X;
            offset.Y -= canvasPanel.AutoScrollPosition.Y;

            cursorPosition = offset;

            if (draw && (toolSelected == 0 || toolSelected == 1))
            {
                rectEnd = offset;
            }
            else if (draw && toolSelected == 2)
            {
                currAnimation.frames[frameSelected].AnchorPoint = new Point(offset.X, offset.Y);
                loadValues = true;
                anchorPosXNumUpDown.Value = offset.X;
                anchorPosYNumUpDown.Value = offset.Y;
                loadValues = false;
            }
        }

        private void canvasPanel_MouseDown(object sender, MouseEventArgs e)
        {
            canvasPanel.Focus();

            if (e.Button == MouseButtons.Left && !previewMode)
            {
                Point offset = e.Location;

                offset.X -= canvasPanel.AutoScrollPosition.X;
                offset.Y -= canvasPanel.AutoScrollPosition.Y;

                if (toolSelected == 0)
                {
                    bool intersected = false;
                    Rectangle mouseRay = new Rectangle(offset.X, offset.Y, 1, 1);
                    Rectangle rect;
                    for (int i = 0; i < currAnimation.frames.Count; ++i)
                    {
                        rect = (Rectangle)currAnimation.frames[i].DrawRect;
                        if (rect.IntersectsWith(mouseRay))
                        {
                            frameSelected = i;
                            intersected = true;

                            LoadValues();

                            break;
                        }
                    }
                    if (!intersected)
                    {
                        loadValues = false;
                        draw = true;
                        rectStart = offset;
                        canvasPanel_MouseMove(sender, e);
                    }
                }
                else if (toolSelected == 1)
                {
                    bool intersected = false;
                    Rectangle mouseRay = new Rectangle(offset.X, offset.Y, 1, 1);
                    Rectangle rect;
                    for (int i = 0; i < currAnimation.frames.Count; ++i)
                    {
                        rect = (Rectangle)currAnimation.frames[i].DrawRect;
                        if (rect.IntersectsWith(mouseRay))
                        {
                            frameSelected = i;
                            intersected = true;
                            
                            LoadValues();
                            break;
                        }
                    }
                    if (intersected)
                    {
                        draw = true;
                        rectStart = offset;
                        canvasPanel_MouseMove(sender, e);
                    }
                    else
                    {
                        frameSelected = -1;
                        loadValues = true;
                        totalFramesNumericUpDown.Value = maxFrames;
                        frameWidthNumUpDown.Value = 0;
                        frameHeightNumUpDown.Value = 0;
                        framePosXNumUpDown.Value = 0;
                        framePosYNumUpDown.Value = 0;

                        collisionWidthNumUpDown.Value = 0;
                        collisionHeightNumUpDown.Value = 0;
                        collisionPosXNumUpDown.Value = 0;
                        collisionPosYNumUpDown.Value = 0;

                        anchorPosXNumUpDown.Value = 0;
                        anchorPosYNumUpDown.Value = 0;

                        eventTextBox.Text = "";
                        loadValues = false;
                    }
                }
                if (toolSelected == 2)
                {
                    bool intersected = false;
                    Rectangle mouseRay = new Rectangle(offset.X, offset.Y, 1, 1);
                    Rectangle rect;
                    for (int i = 0; i < currAnimation.frames.Count; ++i)
                    {
                        rect = (Rectangle)currAnimation.frames[i].DrawRect;
                        if (rect.IntersectsWith(mouseRay))
                        {
                            frameSelected = i;
                            loadValues = true;
                            intersected = true;
                            frameNumTextBox.Text = (i + 1).ToString();
                            timeNumericUpDown.Value = (decimal)currAnimation.frames[i].FrameTime;
                            loadValues = false;
                            break;
                        }
                    }
                    if (intersected)
                    {
                        loadValues = false;
                        draw = true;
                        canvasPanel_MouseMove(sender, e);
                    }
                }
            }
        }

        private void canvasPanel_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (draw)
                {
                    Point offset = e.Location;

                    offset.X -= canvasPanel.AutoScrollPosition.X;
                    offset.Y -= canvasPanel.AutoScrollPosition.Y;

                    if (toolSelected == 0 && rectEnd.X >= 0 && rectEnd.Y >= 0)
                    {
                        draw = false;
                        rectEnd = offset;
                        Frame frame = new Frame();
                        Rectangle frameRect;

                        int width = rectEnd.X - rectStart.X;
                        int height = rectEnd.Y - rectStart.Y;

                        if (width > 0 && height > 0)
                        {
                            frameRect = new Rectangle(rectStart, new Size(width, height));
                        }
                        else
                        {
                            if (width < 0 && height >= 0)
                            {
                                width *= -1;
                                frameRect = new Rectangle(new Point(rectStart.X - width, rectStart.Y), new Size(width, height));
                            }
                            else if (height < 0 && width >= 0)
                            {
                                height *= -1;
                                frameRect = new Rectangle(new Point(rectStart.X, rectStart.Y - height), new Size(width, height));
                            }
                            else
                            {
                                width *= -1;
                                height *= -1;
                                frameRect = new Rectangle(new Point(rectStart.X - width, rectStart.Y - height), new Size(width, height));
                            }
                        }

                        if (width > 5 && height > 5)
                        {
                            frame.DrawRect = frameRect;
                            frame.FrameTime = (int)timeNumericUpDown.Value;

                            currAnimation.frames.Add(frame);
                            maxFrames++;
                            frameSelected = maxFrames - 1;

                            loadValues = true;
                            totalFramesNumericUpDown.Value = maxFrames;
                            frameWidthNumUpDown.Value = width;
                            frameHeightNumUpDown.Value = height;
                            framePosXNumUpDown.Value = frame.DrawRect.Left;
                            framePosYNumUpDown.Value = frame.DrawRect.Top;
                            loadValues = false;
                            frameNumTextBox.Text = frameSelected.ToString();
                        }
                    }
                    else if (toolSelected == 1)
                    {
                        bool intersected = false;
                        int intersectPos = -1;
                        Rectangle mouseRay = new Rectangle(offset.X, offset.Y, 1, 1);
                        Rectangle rect;

                        for (int i = 0; i < currAnimation.frames.Count; ++i)
                        {
                            rect = (Rectangle)currAnimation.frames[i].DrawRect;
                            if (rect.IntersectsWith(mouseRay))
                            {
                                intersected = true;
                                intersectPos = i;
                                break;
                            }
                        }
                        if (intersected)
                        {
                            draw = false;
                            rectEnd = offset;
                            Frame frame = currAnimation.frames[intersectPos];
                            Rectangle frameRect;

                            int width = rectEnd.X - rectStart.X;
                            int height = rectEnd.Y - rectStart.Y;

                            if (width > 0 && height > 0)
                            {
                                frameRect = new Rectangle(rectStart, new Size(width, height));
                            }
                            else
                            {
                                if (width < 0 && height >= 0)
                                {
                                    width *= -1;
                                    frameRect = new Rectangle(new Point(rectStart.X - width, rectStart.Y), new Size(width, height));
                                }
                                else if (height < 0 && width >= 0)
                                {
                                    height *= -1;
                                    frameRect = new Rectangle(new Point(rectStart.X, rectStart.Y - height), new Size(width, height));
                                }
                                else
                                {
                                    width *= -1;
                                    height *= -1;
                                    frameRect = new Rectangle(new Point(rectStart.X - width, rectStart.Y - height), new Size(width, height));
                                }
                            }
                            if (width > 5 && height > 5)
                            {
                                frame.CollisionRect = frameRect;

                                currAnimation.frames[intersectPos] = frame;
                                frameSelected = intersectPos;

                                loadValues = true;
                                collisionWidthNumUpDown.Value = width;
                                collisionHeightNumUpDown.Value = height;
                                collisionPosXNumUpDown.Value = frame.CollisionRect.Left;
                                collisionPosYNumUpDown.Value = frame.CollisionRect.Top;
                                loadValues = false;
                                frameNumTextBox.Text = frameSelected.ToString();
                            }
                        }
                    }
                    else if (toolSelected == 2)
                    {
                        currAnimation.frames[frameSelected].AnchorPoint = new Point(offset.X, offset.Y);
                        loadValues = true;
                        anchorPosXNumUpDown.Value = offset.X;
                        anchorPosYNumUpDown.Value = offset.Y;
                        loadValues = false;
                        draw = false;
                    }
                    else
                        draw = false;
                }
            }

            rectStart = Point.Empty;
            rectEnd = Point.Empty;
        }

        private void timeNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues) 
                currAnimation.frames[frameSelected].frameTime = (int)timeNumericUpDown.Value;
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void framePosXNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                auxRect = new Rectangle((int)framePosXNumUpDown.Value, auxRect.Top, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                currAnimation.frames[frameSelected].drawRect = auxRect;
            }
        }

        private void framePosYNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                auxRect = new Rectangle(auxRect.Left, (int)framePosYNumUpDown.Value, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                currAnimation.frames[frameSelected].drawRect = auxRect;
            }
        }

        private void frameWidthNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                auxRect = new Rectangle(auxRect.Left, auxRect.Top, (int)frameWidthNumUpDown.Value, auxRect.Bottom - auxRect.Top);
                currAnimation.frames[frameSelected].drawRect = auxRect;
            }
        }

        private void frameHeightNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].drawRect;
                auxRect = new Rectangle(auxRect.Left, auxRect.Top, auxRect.Right - auxRect.Left, (int)frameHeightNumUpDown.Value);
                currAnimation.frames[frameSelected].drawRect = auxRect;
            }
        }

        private void canvasPanel_Leave(object sender, EventArgs e)
        {
            if (keyPressed)
            {
                canvasPanel.Focus();
                keyPressed = false;
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Files|*.*|JPEG|*.jpg|PNG|*.png|BMP|*.bmp|XML|*.xml";
            dlg.FilterIndex = 1;
            bool imageLoaded = false;

            if (DialogResult.OK == dlg.ShowDialog())
            {
                filePath = new Uri(dlg.FileName);

                string extension = Path.GetExtension(dlg.FileName);
                if (extension == ".JPG" || extension == ".PNG" || extension == ".BMP" ||
                    extension == ".jpg" || extension == ".png" || extension == ".bmp")
                {
                    if (textureID == -1)
                    {
                        filePath = systemPath.MakeRelativeUri(filePath);
                        if (texManager.LoadTexture(dlg.FileName, 0) != -1)
                            textureID = texManager.LoadTexture(dlg.FileName, 0);
                        else
                            MessageBox.Show("Texture could not be found");

                        imageFilePath = filePath.ToString();

                        canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
                        startTime = Environment.TickCount;
                        currTime = startTime;
                    }
                    else
                    {
                        DialogResult result = MessageBox.Show("Loading a new background image will clear the current image,\n\t\tDo you wish to continue",
                            "AnimationEditor", MessageBoxButtons.YesNo);

                        if (result == DialogResult.Yes)
                        {
                            filePath = systemPath.MakeRelativeUri(filePath);
                            textureID = texManager.LoadTexture(dlg.FileName, 0);
                            imageFilePath = filePath.ToString();

                            canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
                            startTime = Environment.TickCount;
                            currTime = startTime;
                        }
                    }
                }
                if (extension == ".xml" || extension == ".XML")
                {
                    animations.Clear();
                    animationsListBox.Items.Clear();
                    XElement xRoot = XElement.Load(dlg.FileName);
                    //XElement xChild = xRoot.Element("Animation");
                    IEnumerable<XElement> xAnimations = xRoot.Elements("Animation");

                    Uri tempPath;

                    imageFilePath = Convert.ToString(xRoot.Attribute("image").Value);
                    Uri.TryCreate(systemPath, imageFilePath, out tempPath);

                    if (File.Exists(tempPath.LocalPath))
                    {
                        textureID = texManager.LoadTexture(tempPath.LocalPath, 0);
                        imageLoaded = true;
                    }
                    else
                    {
                        MessageBox.Show("Image could not be found, please redefine it's filepath");
                        dlg.Filter = "All Files|*.*|JPEG|*.jpg|PNG|*.png|BMP|*.bmp";
                        dlg.FilterIndex = 1;
                        if (DialogResult.OK == dlg.ShowDialog())
                        {
                            filePath = new Uri(dlg.FileName);
                            imageLoaded = true;
                            extension = Path.GetExtension(dlg.FileName);
                            if (extension == ".JPG" || extension == ".PNG" || extension == ".BMP" ||
                                extension == ".jpg" || extension == ".png" || extension == ".bmp")
                            {
                                filePath = systemPath.MakeRelativeUri(filePath);
                                if (texManager.LoadTexture(dlg.FileName, 0) != -1)
                                    textureID = texManager.LoadTexture(dlg.FileName, 0);
                                else
                                    MessageBox.Show("Texture could not be found");

                                imageFilePath = filePath.ToString();

                                canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
                                startTime = Environment.TickCount;
                                currTime = startTime;
                            }
                        }
                    }
                    if (imageLoaded)
                    {
                        canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
                        startTime = Environment.TickCount;
                        currTime = startTime;
                    
                        foreach (XElement xAnimation in xAnimations)
                        {
                            Animation xmlAnimation = new Animation();

                            XAttribute xName = xAnimation.Attribute("Name");
                            if (xName != null)
                                xmlAnimation.Name = xName.Value;

                            XAttribute xLooping = xAnimation.Attribute("Looping");
                            if (xLooping != null)
                                xmlAnimation.IsLooping = Convert.ToBoolean(xLooping.Value);

                            animationsListBox.Items.Add(xmlAnimation.Name);

                            IEnumerable<XElement> xFrames = xAnimation.Elements("Frame");

                            xmlAnimation.frames = new List<Frame>();

                            foreach (XElement xFrame in xFrames)
                            {
                                Frame xmlFrame = new Frame();

                                XAttribute xTime = xFrame.Attribute("Time");
                                xmlFrame.FrameTime = Convert.ToInt32(xTime.Value);

                                XAttribute xEvent = xFrame.Attribute("Event");
                                xmlFrame.Trigger = Convert.ToString(xEvent.Value);

                                XElement xDrawRect = xFrame.Element("DrawRect");
                                xmlFrame.DrawRect = new Rectangle((int)(xDrawRect.Attribute("Left")),
                                                                    (int)(xDrawRect.Attribute("Top")),
                                                                    (int)(xDrawRect.Attribute("Width")),
                                                                    (int)(xDrawRect.Attribute("Height")));

                                XElement xCollisionRect = xFrame.Element("CollisionRect");
                                xmlFrame.CollisionRect = new Rectangle((int)(xCollisionRect.Attribute("Left")),
                                                                        (int)(xCollisionRect.Attribute("Top")),
                                                                        (int)(xCollisionRect.Attribute("Width")),
                                                                        (int)(xCollisionRect.Attribute("Height")));

                                XElement xAnchorPoint = xFrame.Element("AnchorPoint");
                                xmlFrame.AnchorPoint = new Point((int)(xAnchorPoint.Attribute("X")),
                                                                    (int)(xAnchorPoint.Attribute("Y")));

                                xmlAnimation.frames.Add(xmlFrame);
                            }

                            animations.Add(xmlAnimation);
                        }
                    }
                }
            }

            if (imageLoaded)
                animationsListBox.SelectedIndex = 0;
        }

        private void frameRectButton_Click(object sender, EventArgs e)
        {
            frameRectButton.Enabled = false;
            anchorPointButton.Enabled = true;
            collisionRectButton.Enabled = true;
            toolSelected = 0;
        }

        private void collisionRectButton_Click(object sender, EventArgs e)
        {
            frameRectButton.Enabled = true;
            anchorPointButton.Enabled = true;
            collisionRectButton.Enabled = false;
            toolSelected = 1;
        }

        private void anchorPointButton_Click(object sender, EventArgs e)
        {
            frameRectButton.Enabled = true;
            collisionRectButton.Enabled = true;
            anchorPointButton.Enabled = false;
            toolSelected = 2;
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            currAnimation.frames.Clear();
            maxFrames = 0;
            frameSelected = -1;

            if(textureID !=-1)
                texManager.ReleaseTexture(textureID);
            textureID = -1;

            loadValues = true;
            frameNumTextBox.Text = maxFrames.ToString();
            totalFramesNumericUpDown.Value = maxFrames;
            frameWidthNumUpDown.Value = 0;
            frameHeightNumUpDown.Value = 0;
            framePosXNumUpDown.Value = 0;
            framePosYNumUpDown.Value = 0;

            collisionWidthNumUpDown.Value = 0;
            collisionHeightNumUpDown.Value = 0;
            collisionPosXNumUpDown.Value = 0;
            collisionPosYNumUpDown.Value = 0;

            anchorPosXNumUpDown.Value = 0;
            anchorPosYNumUpDown.Value = 0;

            anchorPosXNumUpDown.Value = 0;
            anchorPosYNumUpDown.Value = 0;
            loadValues = false;
            
            animations.Clear();
            animationsListBox.Items.Clear();

            currAnimation = new Animation();
            currAnimation.IsLooping = true;
            currAnimation.Name = "Untitled Animation";
            currAnimationID = 0;
            currAnimation.frames = new List<Frame>();

            animations.Add(currAnimation);

            animationsListBox.Items.Add("Untitled Animation");
            animationsListBox.SelectedIndex = 0;
        }

        private void anchorPosXNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
                currAnimation.frames[frameSelected].AnchorPoint = new Point((int)anchorPosXNumUpDown.Value, currAnimation.frames[frameSelected].AnchorPoint.Y);
        }

        private void anchorPosYNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
                currAnimation.frames[frameSelected].AnchorPoint = new Point(currAnimation.frames[frameSelected].AnchorPoint.X, (int)anchorPosYNumUpDown.Value);
        }

        private void playAnimationButton_Click(object sender, EventArgs e)
        {
            modeComboBox.SelectedIndex = 1;
            previewMode = true;
            playAnimation = true;
            startTime = Environment.TickCount;
        }

        private void timeNumericUpDown_ValueChanged_1(object sender, EventArgs e)
        {
            if (!loadValues)
                currAnimation.frames[frameSelected].frameTime = (int)timeNumericUpDown.Value;
        }

        private void stopAnimationButton_Click(object sender, EventArgs e)
        {
            modeComboBox.SelectedIndex = 1;
            previewMode = true;
            playAnimation = false;
            frameSelected = 0;
            LoadValues();
        }

        private void pauseAnimationButton_Click(object sender, EventArgs e)
        {
            modeComboBox.SelectedIndex = 1;
            previewMode = true;
            playAnimation = false;
            LoadValues();
        }

        private void prevFrameButton_Click(object sender, EventArgs e)
        {
            modeComboBox.SelectedIndex = 1;
            previewMode = true;
            playAnimation = false;
            frameSelected--;
            if (frameSelected < 0)
            {
                if (currAnimation.IsLooping)
                    frameSelected = currAnimation.frames.Count - 1;
                else
                    frameSelected++;
            }
            LoadValues();
        }

        private void nextFrameButton_Click(object sender, EventArgs e)
        {
            modeComboBox.SelectedIndex = 1;
            previewMode = true;
            playAnimation = false;
            frameSelected++;
            if (frameSelected >= currAnimation.frames.Count)
            {
                if (currAnimation.IsLooping)
                    frameSelected = 0;
                else
                    frameSelected--;
            }
            LoadValues();
        }

        private void animationLoopCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            loopingAnimation = animationLoopCheckBox.Checked;
        }

        private void newAnimationButton_Click(object sender, EventArgs e)
        {
            currAnimation = new Animation();
            currAnimation.IsLooping = true;
            currAnimation.Name = "Untitled Animation";
            currAnimationID++;
            currAnimation.frames = new List<Frame>();

            animations.Add(currAnimation);

            animationsListBox.Items.Add("Untitled Animation");
            animationsListBox.SelectedIndex = animationsListBox.Items.Count-1;

        }

        private void animationNameTextBox_TextChanged(object sender, EventArgs e)
        {
            loadValues = true;
            animationsListBox.Items[currAnimationID] = animationNameTextBox.Text;
            currAnimation.Name = animationNameTextBox.Text;
            loadValues = false;
        }

        private void animationsListBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                currAnimationID = animationsListBox.SelectedIndex;
                currAnimation = animations[currAnimationID];
                maxFrames = animations[currAnimationID].frames.Count;
                frameSelected = 0;
            }
        }

        private void collisionPosXNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                auxRect = new Rectangle((int)collisionPosXNumUpDown.Value, auxRect.Top, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                currAnimation.frames[frameSelected].CollisionRect = auxRect;
            }
        }

        private void collisionPosYNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                auxRect = new Rectangle(auxRect.Left, (int)collisionPosYNumUpDown.Value, auxRect.Right - auxRect.Left, auxRect.Bottom - auxRect.Top);
                currAnimation.frames[frameSelected].CollisionRect = auxRect;
            }
        }

        private void collisionWidthNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                auxRect = new Rectangle(auxRect.Left, auxRect.Top, (int)collisionWidthNumUpDown.Value, auxRect.Bottom - auxRect.Top);
                currAnimation.frames[frameSelected].CollisionRect = auxRect;
            }
        }

        private void collisionHeightNumUpDown_ValueChanged(object sender, EventArgs e)
        {
            if (!loadValues)
            {
                Rectangle auxRect = currAnimation.frames[frameSelected].CollisionRect;
                auxRect = new Rectangle(auxRect.Left, auxRect.Top, auxRect.Right - auxRect.Left, (int)collisionHeightNumUpDown.Value);
                currAnimation.frames[frameSelected].CollisionRect = auxRect;
            }
        }

        private void removeAnimationButton_Click(object sender, EventArgs e)
        {

        }

        private void modeComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (modeComboBox.SelectedIndex == 0)
            {
                previewMode = false;
                if (textureID > -1)
                canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
            }
            else
            {
                if (currAnimation.frames.Count > 0)
                canvasPanel.AutoScrollMinSize = new Size(currAnimation.frames[0].DrawRect.Width, currAnimation.frames[0].DrawRect.Height);
                previewMode = true;
            }
        }

        private void demoModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            previewMode = false;
            modeComboBox.SelectedIndex = 0;
            canvasPanel.AutoScrollMinSize = new Size(texManager.GetTextureWidth(textureID), texManager.GetTextureHeight(textureID));
        }

        private void previewModeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            previewMode = true;
            modeComboBox.SelectedIndex = 1;
            canvasPanel.AutoScrollMinSize = new Size(currAnimation.frames[0].DrawRect.Width, currAnimation.frames[0].DrawRect.Height);
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "All Files|*.*|Xml Files|*.xml";
            dlg.FilterIndex = 2;
            dlg.DefaultExt = "xml";

            if (DialogResult.OK == dlg.ShowDialog())
            {
                XElement root = new XElement("Animations");

                XAttribute xImage = new XAttribute("image", imageFilePath);
                root.Add(xImage);

                for (int i = 0; i<animations.Count; i++)
                {
                    XElement xAnimation = new XElement("Animation");
                    root.Add(xAnimation);

                    XAttribute xName = new XAttribute("Name", animations[i].Name);
                    xAnimation.Add(xName);

                    XAttribute xLooping  = new XAttribute("Looping", animations[i].IsLooping);
                    xAnimation.Add(xLooping);

                    XAttribute xTotalFrames = new XAttribute("TotalFrames", animations[i].frames.Count);
                    xAnimation.Add(xTotalFrames);

                    for (int j = 0; j < animations[i].frames.Count; j++)
                    {
                        XElement xFrame = new XElement("Frame");
                        xAnimation.Add(xFrame);

                        XAttribute xTime = new XAttribute("Time", animations[i].frames[j].FrameTime);
                        xFrame.Add(xTime);

                        XAttribute xEvent = new XAttribute("Event", animations[i].frames[j].Trigger);
                        xFrame.Add(xEvent);

                        //Draw rect
                        XElement xDrawRect = new XElement("DrawRect");
                        xFrame.Add(xDrawRect);

                        XAttribute xTop = new XAttribute("Top", animations[i].frames[j].DrawRect.Top);
                        xDrawRect.Add(xTop);

                        XAttribute xLeft = new XAttribute("Left", animations[i].frames[j].DrawRect.Left);
                        xDrawRect.Add(xLeft);

                        XAttribute xWidth = new XAttribute("Width", animations[i].frames[j].DrawRect.Width);
                        xDrawRect.Add(xWidth);

                        XAttribute xHeight = new XAttribute("Height", animations[i].frames[j].DrawRect.Height);
                        xDrawRect.Add(xHeight);

                        //Collision rect
                        XElement xCollisionRect = new XElement("CollisionRect");
                        xFrame.Add(xCollisionRect);

                        XAttribute xCollTop = new XAttribute("Top", animations[i].frames[j].CollisionRect.Top);
                        xCollisionRect.Add(xCollTop);

                        XAttribute xCollLeft = new XAttribute("Left", animations[i].frames[j].CollisionRect.Left);
                        xCollisionRect.Add(xCollLeft);

                        XAttribute xCollWidth = new XAttribute("Width", animations[i].frames[j].CollisionRect.Width);
                        xCollisionRect.Add(xCollWidth);

                        XAttribute xCollHeight = new XAttribute("Height", animations[i].frames[j].CollisionRect.Height);
                        xCollisionRect.Add(xCollHeight);

                        //Anchor point
                        XElement xAnchorPoint = new XElement("AnchorPoint");
                        xFrame.Add(xAnchorPoint);

                        XAttribute xPosX = new XAttribute("X", animations[i].frames[j].AnchorPoint.X);
                        xAnchorPoint.Add(xPosX);

                        XAttribute xPosY = new XAttribute("Y", animations[i].frames[j].AnchorPoint.Y);
                        xAnchorPoint.Add(xPosY);
                    }
                }

                root.Save(dlg.FileName);
            }
        }

        private void helpToolStripButton_Click(object sender, EventArgs e)
        {
            try
            {
                Process p = new Process();
                p.StartInfo.FileName = "AnimatEd Help.chm";
                p.Start();
            }
            catch (Exception evt)
            {
                MessageBox.Show("Please make sure the help file was included with your installation", "UNABLE TO OPEN HELP FILE");
            }
        }

        private void OpenSystemTextFile()
        {
            try
            {
                using (StreamReader sr = new StreamReader("config\\SystemDir.txt"))
                {
                    systemPath = new Uri(sr.ReadLine());
                }
            }
            catch (Exception e)
            {
                FolderBrowserDialog dlg = new FolderBrowserDialog();
                bool okBtn = false;
                while (!okBtn)
                {
                    if (dlg.ShowDialog() == DialogResult.OK)
                    {
                        okBtn = true;
                        systemPath = new Uri(dlg.SelectedPath);
                        if (!Directory.Exists("config"))
                            Directory.CreateDirectory("config");

                        using (StreamWriter sw = new StreamWriter("config\\SystemDir.txt"))
                        {
                            sw.WriteLine(dlg.SelectedPath);
                        }
                    }
                }
            }
        }

        private void eventTextBox_TextChanged(object sender, EventArgs e)
        {
            if(currAnimation.frames.Count > 0)
                currAnimation.frames[frameSelected].Trigger = eventTextBox.Text;
        }

        private void LoadValues()
        {
            loadValues = true;
            frameWidthNumUpDown.Value = (decimal)(currAnimation.frames[frameSelected].DrawRect.Right - currAnimation.frames[frameSelected].DrawRect.Left);
            frameHeightNumUpDown.Value = (decimal)(currAnimation.frames[frameSelected].DrawRect.Bottom - currAnimation.frames[frameSelected].DrawRect.Top);
            framePosXNumUpDown.Value = currAnimation.frames[frameSelected].DrawRect.Left;
            framePosYNumUpDown.Value = currAnimation.frames[frameSelected].DrawRect.Top;

            collisionPosXNumUpDown.Value = currAnimation.frames[frameSelected].CollisionRect.Left;
            collisionPosYNumUpDown.Value = currAnimation.frames[frameSelected].CollisionRect.Top;
            collisionWidthNumUpDown.Value = currAnimation.frames[frameSelected].CollisionRect.Right - currAnimation.frames[frameSelected].CollisionRect.Left;
            collisionHeightNumUpDown.Value = currAnimation.frames[frameSelected].CollisionRect.Bottom - currAnimation.frames[frameSelected].CollisionRect.Top;

            if (currAnimation.frames[frameSelected].AnchorPoint.X > 0 && currAnimation.frames[frameSelected].AnchorPoint.Y > 0)
            {
                anchorPosXNumUpDown.Value = currAnimation.frames[frameSelected].AnchorPoint.X;
                anchorPosYNumUpDown.Value = currAnimation.frames[frameSelected].AnchorPoint.Y;
            }
            else
            {
                anchorPosXNumUpDown.Value = 0;
                anchorPosYNumUpDown.Value = 0;
            }

            eventTextBox.Text = currAnimation.frames[frameSelected].Trigger;
            frameNumTextBox.Text = (frameSelected + 1).ToString();
            timeNumericUpDown.Value = (decimal)currAnimation.frames[frameSelected].FrameTime;
            loadValues = false;
        }

        private void changeSystemPathToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                systemPath = new Uri(dlg.SelectedPath);
                if (!Directory.Exists("config"))
                    Directory.CreateDirectory("config");

                using (StreamWriter sw = new StreamWriter("config\\SystemDir.txt"))
                {
                    sw.WriteLine(dlg.SelectedPath);
                }
            }
        }
    }
}